package mz.behaveas.model.spec {
	import mz.behaveas.model.expectation.NotImplementedExpectation;
	import mz.behaveas.model.expectation.IgnoredExpectation;
	import mz.behaveas.model.expectation.MallformedExpectation;
	import mz.behaveas.model.expectation.Expectation;

	/**
	 * @author maxim.zaks@gmail.com
	 */
	public class CorrectSpecification implements Specification {

		private var _description : String;
		private var expectations : Vector.<Expectation> = new Vector.<Expectation>();
		private var malformedIndexes : Vector.<int> = new Vector.<int>();
		private var ignoredIdexes : Vector.<int> = new Vector.<int>();
		private var notImplementedIndexes : Vector.<int> = new Vector.<int>();
		private var correctExpectationIndexes : Vector.<int> = new Vector.<int>();
		private var notCorrectExpectationIndexes : Vector.<int> = new Vector.<int>();

		public function CorrectSpecification(description : String) {
			_description = description;
		}

		public function addExpectation(exp : Expectation) : void {
			expectations.push(exp);
			if(exp is MallformedExpectation) {
				malformedIndexes.push(expectations.length);
			} else if(exp is IgnoredExpectation) {
				ignoredIdexes.push(expectations.length);
			} else if(exp is NotImplementedExpectation) {
				notImplementedIndexes.push(expectations.length);
			}
		}

		public function get description() : String {
			return _description + "\n" + "This specification has " + expectations.length + " expectations. " + malformedIndexes.length + " malformed ," + ignoredIdexes.length + " ignored and " + notImplementedIndexes.length + " not implemented.";
		}
		
		public function runExpectations(listener : SpecRunListener) : void {
			var expectationIndex : int = 1;
			for each(var expectation : Expectation in expectations) {
				
				listener.expectationStarted(expectation.description, expectationIndex);
				if(expectation.isCorrect){
					  correctExpectationIndexes.push(expectationIndex);
				}else{
					notCorrectExpectationIndexes.push(expectationIndex);
					listener.expectationFailed(expectationIndex);
					if(expectation.getError()){
						listener.expectationFiredError(expectation.getError());
					}
					
				}
				listener.expectationDone(expectation.report);
				expectationIndex++;
			}
		}

		public function get report() : String {
			return "This specification has " + correctExpectationIndexes.length + " correct, and " + notCorrectExpectationIndexes.length + " not correct expectations.";
		}
		
		public function get numberOfNotCorrectExpectations() : int {
			return notCorrectExpectationIndexes.length;
		}
		
		public function get numberOfExpectations() : int {
			return expectations.length;
		}
	}
}
